﻿using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Threading.Tasks;

namespace lwzlz.Core.Repository
{
    /// <summary>
    /// 仓储接口
    /// 基本CRUD操作
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    public interface IRepository<TEntity> where TEntity : ModelBase, new()
    {
        /// <summary>
        /// 开始数据库事务
        /// </summary>
        /// <returns></returns>
        IDbTransaction BeginTransaction();

        #region 增
        int? Insert(TEntity entity, IDbTransaction transaction = null, int? commandTimeout = null);
        int? Insert<T>(T entity, IDbTransaction transaction = null, int? commandTimeout = default(int?)) where T : ModelBase, new();
        Task<int?> InsertAsync(TEntity entity, IDbTransaction transaction = null, int? commandTimeout = null);
        #endregion

        #region 删
        int Delete(TEntity entity, IDbTransaction transaction = null, int? commandTimeout = null);
        int Delete(object id, IDbTransaction transaction = null, int? commandTimeout = null);
        int DeleteList(object whereConditions, IDbTransaction transaction = null, int? commandTimeout = null);
        int DeleteList(string whereConditions, object param = null, IDbTransaction transaction = null, int? commandTimeout = null);


        Task<int> DeleteAsync(TEntity entity, IDbTransaction transaction = null, int? commandTimeout = null);
        Task<int> DeleteAsync(object id, IDbTransaction transaction = null, int? commandTimeout = null);
        Task<int> DeleteListAsync(object whereConditions, IDbTransaction transaction = null, int? commandTimeout = null);
        Task<int> DeleteListAsync(string whereConditions, object param = null, IDbTransaction transaction = null, int? commandTimeout = null);
        #endregion

        #region 改
        int Update(TEntity entity, IDbTransaction transaction = null, int? commandTimeout = null);
        Task<int> UpdateAsync(TEntity entity, IDbTransaction transaction = null, int? commandTimeout = null);
        #endregion

        #region 查
        TEntity Get(object id, IDbTransaction transaction = null, int? commandTimeout = null);
        T Get<T>(object id, IDbTransaction transaction = null, int? commandTimeout = default(int?)) where T : ModelBase;
        IEnumerable<TEntity> Query(string sql, object param = null, IDbTransaction transaction = null, bool buffered = true,
            int? commandTimeout = default(int?), CommandType? commandType = default(CommandType?));
        IEnumerable<T> Query<T>(string sql, object param = null, IDbTransaction transaction = null, bool buffered = true,
            int? commandTimeout = default(int?), CommandType? commandType = default(CommandType?)) where T : class, new();
        dynamic QuerySingle(string sql, object param = null, IDbTransaction transaction = null,
            int? commandTimeout = default(int?), CommandType? commandType = default(CommandType?));
        IEnumerable<dynamic> QueryDynamic(string sql, object param = null, IDbTransaction transaction = null, bool buffered = true,
            int? commandTimeout = default(int?), CommandType? commandType = default(CommandType?));
        TEntity QueryFirstOrDefault(string sql, object param = null, IDbTransaction transaction = null,
            int? commandTimeout = null, CommandType? commandType = null);
        IEnumerable<TEntity> GetList();
        IEnumerable<TEntity> GetList(object whereConditions, IDbTransaction transaction = null, int? commandTimeout = null);
        IEnumerable<TEntity> GetList(string whereConditions, object param = null, IDbTransaction transaction = null, int? commandTimeout = null);
        IEnumerable<TEntity> GetListPaged(int pageNumber, int rowsPerPage, string conditions, string orderby,
            object param = null, IDbTransaction transaction = null, int? commandTimeout = null);


        IEnumerable<T> GetQueryPaged<T>(int pageNumber, int rowsPerPage, string orderby, string sql, object param = null,
            IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) where T : class, new();
        IEnumerable<dynamic> GetDynamicPaged(int pageNumber, int rowsPerPage, string orderby, string sql, object param = null,
            IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null);
        int RecordCount(string conditions = "", object param = null, IDbTransaction transaction = null, int? commandTimeout = null);
        int RecordQueryCount(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = default(int?));





        Task<TEntity> GetAsync(object id, IDbTransaction transaction = null, int? commandTimeout = null);
        Task<IEnumerable<TEntity>> QueryAsync(string sql, object param = null, IDbTransaction transaction = null,
            int? commandTimeout = default(int?), CommandType? commandType = default(CommandType?));
        Task<IEnumerable<T>> QueryAsync<T>(string sql, object param = null, IDbTransaction transaction = null,
            int? commandTimeout = default(int?), CommandType? commandType = default(CommandType?)) where T : ModelBase, new();
        Task<IEnumerable<dynamic>> QueryDynamicAsync(string sql, object param = null, IDbTransaction transaction = null,
            int? commandTimeout = default(int?), CommandType? commandType = default(CommandType?));
        Task<TEntity> QueryFirstOrDefaultAsync(string sql, object param = null, IDbTransaction transaction = null,
            int? commandTimeout = null, CommandType? commandType = null);
        Task<IEnumerable<TEntity>> GetListAsync();
        Task<IEnumerable<TEntity>> GetListAsync(object whereConditions, IDbTransaction transaction = null, int? commandTimeout = null);
        Task<IEnumerable<TEntity>> GetListAsync(string whereConditions, object param = null, IDbTransaction transaction = null, int? commandTimeout = null);
        Task<IEnumerable<TEntity>> GetListPagedAsync(int pageNumber, int rowsPerPage, string conditions, string orderby,
            object param = null, IDbTransaction transaction = null, int? commandTimeout = null);
        Task<int> RecordCountAsync(string conditions = "", object param = null, IDbTransaction transaction = null, int? commandTimeout = null);
        #endregion

        #region 执行
        int Execute(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null);
        Task<int> ExecuteAsync(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null);
        #endregion

        #region 其他

        /// <summary>
        /// 根据sql获取DataTable
        /// </summary>
        /// <param name="sql">sql语句</param>
        /// <param name="paras">参数</param>
        /// <param name="tran">事务</param>
        /// <returns></returns>
        DataTable LoadDTbySQL(string sql, SqlParameter[] paras = null, IDbTransaction tran = null);
        #endregion
    }
}
